#**************************************************************************
#*********************---------------------------------**********************
#********************|    Copyright (c) 2003 - 2022    |*********************
#********************|      by VIRE Technologies.        |*********************
#********************|       All Rights Reserved           |*********************
#*********************---------------------------------**********************
#**************************************************************************
#
# If any question, please write to VIRE Technologies for
# more information:
#			Techart Plaza, A16, No.30 XueYuan Road,
#			Haidian District Beijing 100083,
#			P.R. China
#
# For more, please visit company website: www.vire.cn
#**************************************************************************

# This file defines the commands and macros that are used
# to support a software build. It is intended to be included
# by the top-level CMakeLists.txt file.

# GCC Compiler version:
#---Obtain the major and minor version of the GNU compiler---
MACRO(get_gcc_version MAJOR_VAR MINOR_VAR PATCH_VAR)
   # cache the results so that we don't have execute gcc for each lookup
  get_property(ALREADY_SET GLOBAL PROPERTY SWDEV_GCC_MAJOR SET)
  IF (NOT ALREADY_SET)
     exec_program(${CMAKE_C_COMPILER} ARGS "-dumpversion" OUTPUT_VARIABLE _gcc_version_info)
     string(REGEX REPLACE "^([0-9]+).*$"                   "\\1" GCC_MAJOR ${_gcc_version_info})
     string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*$"          "\\1" GCC_MINOR ${_gcc_version_info})
     string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" GCC_PATCH ${_gcc_version_info})

     if(GCC_PATCH MATCHES "\\.+")
       set(GCC_PATCH "")
     endif()
     if(GCC_MINOR MATCHES "\\.+")
       set(GCC_MINOR "")
     endif()
     if(GCC_MAJOR MATCHES "\\.+")
       set(GCC_MAJOR "")
     endif()
     set_property(GLOBAL PROPERTY SWDEV_GCC_MAJOR "${GCC_MAJOR}")
     set_property(GLOBAL PROPERTY SWDEV_GCC_MINOR "${GCC_MINOR}")
     set_property(GLOBAL PROPERTY SWDEV_GCC_PATCH "${GCC_PATCH}")
     message(STATUS "Found GCC. Major version ${GCC_MAJOR}, minor version ${GCC_MINOR}")
  ENDIF()
  get_property(${MAJOR_VAR} GLOBAL PROPERTY "SWDEV_GCC_MAJOR")
  get_property(${MINOR_VAR} GLOBAL PROPERTY "SWDEV_GCC_MINOR")
  get_property(${PATCH_VAR} GLOBAL PROPERTY "SWDEV_GCC_PATCH")
ENDMACRO()

# Force the inclusion of the '_input' file. Used by IDE build
MACRO(ADD_FORCED_INCLUDE _input)
   GET_FILENAME_COMPONENT(_name ${_input} NAME)
   SET(_name ${_input})
   IF(MSVC)
      set_property(GLOBAL PROPERTY COMPILE_FLAGS "/FI${_name}")
   ENDIF(MSVC)
   IF(CMAKE_COMPILER_IS_GNUCXX)
      set_property(GLOBAL PROPERTY COMPILE_FLAGS "-include ${_name}")
   ENDIF(CMAKE_COMPILER_IS_GNUCXX)
ENDMACRO()

# Define compiler definitions and shared library install locations that we want for every project
if(WIN32)
   if(MSVC)
      add_definitions("-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS")
      add_compile_options(/MP /EHsc)
      if (MSVC_VERSION GREATER 1900)
         # Acknowledge MSVC 2017 std::tr1 deprecation and silence output warning.
         # Only required for googletest usage, tracked at https://github.com/google/googletest/issues/1111
         add_definitions(-D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
      endif()
   endif()
   if(BUILD_SHARED_LIBS)
      add_definitions("-DSWDEV_ALL_USE_DLL")
   endif(BUILD_SHARED_LIBS)
   # On windows, the dll's must reside in the same path as the .exe
   if("${INSTALL_DLL_PATH}" STREQUAL "")
      set(INSTALL_DLL_PATH .)
   endif("${INSTALL_DLL_PATH}" STREQUAL "")
else(WIN32)
   # On linux, we can use rpath to locate so's in a subdirectory
   if("${INSTALL_DLL_PATH}" STREQUAL "")
      set(INSTALL_DLL_PATH ./lib)
   endif("${INSTALL_DLL_PATH}" STREQUAL "")
   # disable strict aliasing optimization (for UtFunction)
   add_definitions("-fno-strict-aliasing")
endif(WIN32)

if("${INSTALL_EXE_PATH}" STREQUAL "")
   set(INSTALL_EXE_PATH .)
endif("${INSTALL_EXE_PATH}" STREQUAL "")

if("${INSTALL_PLUGIN_PATH}" STREQUAL "")
   set(INSTALL_PLUGIN_PATH .)
endif("${INSTALL_PLUGIN_PATH}" STREQUAL "")

# Setup install of plugin project libraries. Used by extension and sub-project
# CMakeLists.txt files.
macro(ewxdev_plugin_install TARGET PLUGIN_DIR)
   ewxdev_lib_install(${TARGET} ${INSTALL_PLUGIN_PATH}/${PLUGIN_DIR})
   # Move plug-in into subdirectory
   # Required in order to run in debug from Visual Studio
   add_custom_command(TARGET ${TARGET} POST_BUILD
                      COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${TARGET}>/${PLUGIN_DIR}" VERBATIM
                      COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${PLUGIN_DIR} VERBATIM)
endmacro()

# Setup install of project libraries. Used by extension and sub-project
# CMakeLists.txt files.
# ewxdev_lib_install(TARGET [DESTINATION])
# Optional argument specifies destination directory for RUNTIME and LIBRARY target files (default: ${INSTALL_DLL_PATH})
macro(ewxdev_lib_install TARGET)
   get_target_property(library_type ${TARGET} TYPE)

   if("${library_type}" STREQUAL "SHARED_LIBRARY")
      set(DEST_DIR ${INSTALL_DLL_PATH})
      if(${ARGC} GREATER 1)
         set(DEST_DIR ${ARGV1})
      endif()
      if(DEFINED INSTALL_LIB_PATH AND NOT "${INSTALL_LIB_PATH}" STREQUAL "")
         install(TARGETS ${TARGET}
                 RUNTIME DESTINATION ${DEST_DIR} COMPONENT Runtime
                 PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
                             GROUP_EXECUTE GROUP_READ
                             WORLD_EXECUTE WORLD_READ
                 ARCHIVE DESTINATION ${INSTALL_LIB_PATH} COMPONENT Archive
                 PERMISSIONS OWNER_WRITE OWNER_READ
                             GROUP_READ
                             WORLD_READ
                 LIBRARY DESTINATION ${DEST_DIR} COMPONENT Library
                 PERMISSIONS OWNER_WRITE OWNER_READ
                             GROUP_READ
                             WORLD_READ)
      else()
         install(TARGETS ${TARGET}
                 RUNTIME DESTINATION ${DEST_DIR} COMPONENT Runtime
                 PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
                             GROUP_EXECUTE GROUP_READ
                             WORLD_EXECUTE WORLD_READ
                 LIBRARY DESTINATION ${DEST_DIR} COMPONENT Library
                 PERMISSIONS OWNER_WRITE OWNER_READ
                             GROUP_READ
                             WORLD_READ)
      endif()

      # Install PDB file for Debug configuration when using MSVC
      if(MSVC)
         install(FILES $<TARGET_PDB_FILE:${TARGET}> DESTINATION ${DEST_DIR}
                 CONFIGURATIONS Debug RelWithDebInfo COMPONENT Runtime)
      endif()
   endif()
endmacro()

# Add libraries for Windows sockets
macro(link_sockets TARGET)
   if(WIN32)
      target_link_libraries(${TARGET} ws2_32)
   endif(WIN32)
endmacro(link_sockets TARGET)

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)

IF(NOT WIN32)
find_package(Threads)
set(SWDEV_THREAD_LIB Threads::Threads)
ENDIF()

if(WIN32)
   set(SWDEV_DL_LIB)
else(WIN32)
   set(SWDEV_DL_LIB dl)
endif(WIN32)

# Indicate the stable branch for the purposes of managing configurations 
# across releases, e.g. for 3rd party and resource dependencies 
set(SWDEV_BASE_BRANCH "release_2p6")

# The add_subdirectory() command can only be used once for a directory
# this wraps add_subdirectory() so that it only executes the first time
# We assume TARGET_NAME will be the same as the bin subdirectory name
macro(try_add_subdirectory DIR TARGET_NAME)
   if(NOT TARGET ${TARGET_NAME})
      add_subdirectory(${DIR} ${TARGET_NAME})
   endif(NOT TARGET ${TARGET_NAME})
endmacro(try_add_subdirectory DIR TARGET_NAME)

# Recurse directory (SRC_DIR) installing that directory with the source files
# matching the pattern under INSTALL_SOURCE_ROOT/TARGET_DIR
macro(install_sources SRC_DIR TARGET_DIR)
   if(NOT "${INSTALL_SOURCE_ROOT}" STREQUAL "")
      install(DIRECTORY ${SRC_DIR} DESTINATION ${INSTALL_SOURCE_ROOT}/${TARGET_DIR} COMPONENT Source
              FILES_MATCHING PATTERN "*.cpp"
                             PATTERN "*.hpp"
                             PATTERN "*.hxx"
                             PATTERN "*.cxx"
                             PATTERN "*.c"
                             PATTERN "*.h"
                             PATTERN "*.txt"
                             PATTERN "Doxyfile"
                             PATTERN "CMakeLists.txt"
                             PATTERN "Makefile"
                             PATTERN "README"
                             PATTERN "*_module"
                             PATTERN "*_plugin"
                             PATTERN "*.cmake"
                             PATTERN "*.in"
                             PATTERN "*.rc"
                             PATTERN "*.ico"
                             PATTERN "*.png"
                             PATTERN "*.timestamp" EXCLUDE
                             PATTERN ".git"        EXCLUDE
                             PATTERN "__pycache__" EXCLUDE
                             ${ARGN}
             )
   endif()
endmacro(install_sources SRC_DIR TARGET_DIR)

# Recurse directory (SRC_DIR) installing that directory with all files,
# except those excluded, under INSTALL_SOURCE_ROOT/TARGET_DIR
macro(install_sources_all_files SRC_DIR TARGET_DIR)
   if(NOT "${INSTALL_SOURCE_ROOT}" STREQUAL "")
      install(DIRECTORY ${SRC_DIR} DESTINATION ${INSTALL_SOURCE_ROOT}/${TARGET_DIR} COMPONENT Source
              FILES_MATCHING PATTERN "*.*"
                             PATTERN "Makefile"
                             PATTERN "README"
                             PATTERN "*_module"
                             PATTERN "*_plugin"
                             PATTERN ".*.swp"         EXCLUDE
                             PATTERN ".*.swo"         EXCLUDE
                             PATTERN "*.timestamp"    EXCLUDE
                             PATTERN ".git"           EXCLUDE
                             # doesn't work:  PATTERN ".*" EXCLUDE
                             PATTERN "AAA_PACKAGE"    EXCLUDE
                             PATTERN "__pycache__"    EXCLUDE
                             ${ARGN}
             )
   endif()
endmacro()


# A ewx extension should report grammar for new inputs using this macro
# This copies the grammar file to an intermediate directory on build
# and adds the grammar file to a list of all grammar files for installation
macro(ewx_grammar_file SOURCES_VAR GRAMMAR_FILE_PATH)
   get_filename_component(GRAMMAR_FILE_NAME "${GRAMMAR_FILE_PATH}" NAME)
   add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/grammar/${GRAMMAR_FILE_NAME}"
                      COMMAND ${CMAKE_COMMAND} -E copy "${GRAMMAR_FILE_PATH}" "${CMAKE_BINARY_DIR}/grammar/${GRAMMAR_FILE_NAME}"
                      MAIN_DEPENDENCY "${GRAMMAR_FILE_PATH}"
                     )
   set(${SOURCES_VAR} ${${SOURCES_VAR}} ${GRAMMAR_FILE_PATH})
   set_property(GLOBAL APPEND PROPERTY WSF_GRAMMAR_FILES "${GRAMMAR_FILE_PATH}")
endmacro()

# Install all files (leading arguments) (SRC_FILES) into the TARGET_DIR (last argument),
# install_source_files(SRC_FILE_1 SRC_FILE_2, ... SRC_FILE_N, TARGET_DIR)
macro(install_source_files)
   if (ARGC LESS 2)
      message(FATAL_ERROR "Incorrect number of arguments for install_source_files in swdev_project.cmake.")
   endif()

   if(NOT "${INSTALL_SOURCE_ROOT}" STREQUAL "")
      set(SRC_FILES "${ARGV}")
      MATH(EXPR TGT_INDEX "${ARGC}-1")
      list(GET SRC_FILES "${TGT_INDEX}" TARGET_DIR)
      list(REMOVE_AT SRC_FILES "${TGT_INDEX}")
      install(FILES ${SRC_FILES} DESTINATION ${INSTALL_SOURCE_ROOT}/${TARGET_DIR} COMPONENT Source)
   endif()
endmacro()

# Recurse directory (SRC_DIR) installing that directory with the source files
# matching the pattern under INSTALL_SOURCE_ROOT/TARGET_DIR
macro(install_tests SRC_DIR TARGET_DIR)
   if(NOT "${INSTALL_SOURCE_ROOT}" STREQUAL "")
      install(DIRECTORY ${SRC_DIR} DESTINATION ${INSTALL_SOURCE_ROOT}/${TARGET_DIR} COMPONENT Source
              USE_SOURCE_PERMISSIONS
              PATTERN ".*"             EXCLUDE
              PATTERN "*.lis"          EXCLUDE
              PATTERN "*.aer"          EXCLUDE
              PATTERN "*.evt"          EXCLUDE
              PATTERN "*.rep"          EXCLUDE
              PATTERN "*.log"          EXCLUDE
              PATTERN "*.db"           EXCLUDE
              PATTERN "*.tmp"          EXCLUDE
              PATTERN "*.gnu"          EXCLUDE
              PATTERN "*.plt"          EXCLUDE
              PATTERN "*.sed"          EXCLUDE
              PATTERN "__pycache__"    EXCLUDE
              ${ARGN}
             )
   endif()
endmacro(install_tests SRC_DIR TARGET_DIR)

# Take a list of relative or absolute paths and assign to VARNAME the absolute paths
macro(ewxdev_absolute_paths VARNAME)
   set(${VARNAME})
   foreach(ARG ${ARGN})
      if (IS_ABSOLUTE "${ARG}")
         GET_FILENAME_COMPONENT(ARG_ABS_PATH "${ARG}" ABSOLUTE)
         set(${VARNAME} ${${VARNAME}} "${ARG_ABS_PATH}")
      elseif(EXISTS "${ARG}")
         GET_FILENAME_COMPONENT(ARG_ABS_PATH "${ARG}" ABSOLUTE)
         set(${VARNAME} ${${VARNAME}} "${ARG_ABS_PATH}")
      elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${ARG}")
         GET_FILENAME_COMPONENT(ARG_ABS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${ARG}" ABSOLUTE)
         set(${VARNAME} ${${VARNAME}} "${ARG_ABS_PATH}")
      endif()
   endforeach()
endmacro()

# Microsoft's compilers need to use the /bigobj flag for source files containing many symbols
# This macro marks a list of sources as large (symbols over the 2^16 limit)
# These options tell the compiler to use 32-bit addressing and enable inline
# expansion, which cuts down on the symbol count about 30%
MACRO(large_source_files)
   IF(WIN32)
      FOREACH(SRC ${ARGV})
         set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS "/bigobj /Ob2")
      ENDFOREACH()
   ENDIF()
ENDMACRO()

# Suffix libraries with a semi-unique ending
MACRO(use_swdev_lib_suffixes)
   IF(WIN32)
      SET(CMAKE_DEBUG_POSTFIX "_d")
   ELSE()
      get_gcc_version(GCC_MAJOR GCC_MINOR GCC_PATCH)
      # 64-bit detection
      SET(pARCH_SUFFIX)
      if(CMAKE_SIZEOF_VOID_P EQUAL 8)
         string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "-m32" IS_32_BIT)
         if ("${IS_32_BIT}" STREQUAL "-1")
            set(pARCH_SUFFIX "m64")
         endif()
      endif()
      SET(CMAKE_DEBUG_POSTFIX "_d_ln${GCC_MAJOR}${pARCH_SUFFIX}")
      SET(CMAKE_RELEASE_POSTFIX "_ln${GCC_MAJOR}${pARCH_SUFFIX}")
   ENDIF()
ENDMACRO()

# Add Microsoft redistributable runtime libs for Windows
MACRO(ewxdev_install_c_runtime)
   if(MSVC)
      # May need this for mixed plugins using different versions of libraries.
      # https://blog.kitware.com/deploying-on-windows-with-dll-manifest-issues/
      # http://msdn.microsoft.com/en-us/library/aa374224(v=vs.85).aspx
      #if (MSVC)   # Do not generate manifests for the plugins - caused issues loading plugins
      #   set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO")
      #endif()
      if (MSVC_VERSION GREATER 1800)
         set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
      endif(MSVC_VERSION GREATER 1800)
      set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INSTALL_DLL_PATH})
      set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE)
      set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT MSVC_LIBS)
      include(InstallRequiredSystemLibraries)
   endif(MSVC)
ENDMACRO()

# Add executable to CPack list for menu creation with installers
macro(add_to_start_menu TARGET NAME)
   get_target_property(WSF_EXE_NAME ${PROJECT_NAME} OUTPUT_NAME)
   if (${WSF_EXE_NAME} STREQUAL WSF_EXE_NAME-NOTFOUND)
      set(WSF_EXE_NAME ${TARGET})
   endif()

   get_property(EXECUTABLES GLOBAL PROPERTY START_MENU_EXECUTABLES)
   set(EXECUTABLES ${EXECUTABLES} ${WSF_EXE_NAME} ${NAME})
   set_property(GLOBAL PROPERTY START_MENU_EXECUTABLES "${EXECUTABLES}")

   get_property(LINKS GLOBAL PROPERTY DESKTOP_LINKS)
   set(LINKS ${LINKS} ${WSF_EXE_NAME})
   set_property(GLOBAL PROPERTY DESKTOP_LINKS "${LINKS}")
endmacro()

# Sets the compiler warning level for a project
macro(ewxdev_warning_level TARGET)
   if(WIN32)
      #  C4266 (level 4) 'function': no override available for virtual member function from base 'type'; function is hidden
      # ADD_DEFINITIONS(/W3 /w34706 /w34264 /w34266)
      target_compile_options(${TARGET} PRIVATE "/W3")
   endif()
   if(CMAKE_COMPILER_IS_GNUCXX)
      target_compile_options(${TARGET} PRIVATE "-Wall")
   endif()
endmacro()

# Are we compiling 64 or 32 bit
# usage:   ewxdev_is_64bit(is64)
#          if (is64) ...
MACRO(ewxdev_is_64bit OUTVAR)
   SET(${OUTVAR} FALSE)
   IF (CMAKE_CL_64)
      SET(${OUTVAR} TRUE)
   ELSE()
      IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
         STRING(FIND "${CMAKE_EXE_LINKER_FLAGS}" "-m32" IS_32_BIT)
         IF ("${IS_32_BIT}" STREQUAL "-1")
            SET(${OUTVAR} TRUE)
         ENDIF()
      ENDIF()
   ENDIF()
ENDMACRO()

#此方法主要用于库的导出头文件生成，保证在不同平台上都是用小写的文件名
MACRO(ewxdev_generate_export_header target_name)
   if(NOT TARGET ${target_name})
      message(FATAL_ERROR "Not Target....")
   endif()

   set(options)
   set(oneValueArgs OUT_HEADER)
   set(multiValueArgs)
   cmake_parse_arguments(_args "${options}" "${oneValueArgs}"
                  "${multiValueArgs}" ${ARGN} )

   string(TOLOWER ${target_name} lower_target_name)
   generate_export_header(${target_name}
	   BASE_NAME ${lower_target_name} 
	   EXPORT_FILE_NAME ${lower_target_name}_export.h
   )
   SET(${_args_OUT_HEADER} ${CMAKE_CURRENT_BINARY_DIR}/${lower_target_name}_export.h)
ENDMACRO()


#ewxdev_external_target_out_put_base
#此命令将生成插件目标生成到${EWX_SDK_ROOT}/bin/${target_dir}
#<target>:目标
#<target_dir>：目录
macro(ewxdev_external_target_out_put_base target target_dir)
   set(options VS_DEBUGGER_WORKING_DIRECTORY)
   set(oneValueArgs EWX_DEBUG_ROOT)
   set(multiValueArgs)
   cmake_parse_arguments(_args "${options}" "${oneValueArgs}"
                  "${multiValueArgs}" ${ARGN} )

   IF(EXISTS ${_args_EWX_DEBUG_ROOT})
      set(bin_dir ${_args_EWX_DEBUG_ROOT})
   ELSEIf(EXISTS ${EWX_SDK_ROOT})
      set(bin_dir ${EWX_SDK_ROOT}/bin)
   ELSE()
      message(FATAL_ERROR "This Macro Only Use For External Plugins Output...")
   endif()

	set(out_put_dir ${bin_dir}/${target_dir})
	message(NOTICE "==ewxdev_external_target_out_put_base==: set target=[${target}] ${out_put_dir}")

   IF(WIN32)
      set_target_properties(${target} PROPERTIES 
         VS_DEBUGGER_WORKING_DIRECTORY ${bin_dir})
      set_target_properties(${target} PROPERTIES
         RUNTIME_OUTPUT_DIRECTORY_RELEASE ${out_put_dir}
			PDB_OUTPUT_DIRECTORY_RELEASE ${bin_dir}
         RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${out_put_dir}
			PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO ${bin_dir}
      )
   ELSE()
      set_target_properties(${target} PROPERTIES
         RUNTIME_OUTPUT_DIRECTORY ${out_put_dir}
         ARCHIVE_OUTPUT_DIRECTORY ${out_put_dir}
         LIBRARY_OUTPUT_DIRECTORY ${out_put_dir}
			PDB_OUTPUT_DIRECTORY_RELEASE ${bin_dir}
         RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${out_put_dir}
			PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO ${bin_dir}
      )
   ENDIF()
endmacro()

#此命令将生成插件目标生成到${EWX_SDK_ROOT}/bin
macro(ewxdev_external_target_out_put_bin target)
   ewxdev_external_target_out_put_base(${target} "" ${ARGN})
endmacro()

#ewxdev_external_plugin_out_put
#此命令将生成插件目标生成到插件目录
#
macro(ewxdev_external_plugin_out_put target PLUGIN_DIR)
   ewxdev_external_target_out_put_base(${target} ${PLUGIN_DIR} ${ARGN})
endmacro()

#此代码将相关的脚本拷贝到${EWX_SDK_ROOT}/bin/grammer
macro(ewxdev_external_plugin_grammer TARGET grammer_path)
   if(NOT EXISTS ${EWX_SDK_ROOT})
      message(FATAL_ERROR "This Macro Only Use For External Plugins Output...")
   endif()
	set(dst_grammer_dir ${EWX_SDK_ROOT}/bin/grammar)

   file(GLOB grammer_files ${grammer_path}/*.ag)
   list(LENGTH grammer_files len_grammers_files)
   if(${len_grammers_files} GREATER 0)
      list(JOIN grammer_files "\r\n  " str_files)
      add_custom_command(TARGET ${TARGET} POST_BUILD
                  COMMENT "---->Copy ${TARGET} GrammerFiles \n${str_files}\n  To \n${dst_grammer_dir}"
                  COMMAND ${CMAKE_COMMAND} -E copy ${grammer_files} ${dst_grammer_dir}
      )
   endif()
endmacro()

#==============================================================


#此宏处理多语言的自动安装到运行目录,并设置可执行程序的工作目录
OPTION(EWX_WORKING_DIRECTORY_USE_PROJECT_WORKING_DIR "" OFF)
macro(ewxdev_exec_target_working_directory TARGET)
   if(NOT TARGET ${TARGET})
      message(FATAL_ERROR "ewxdev_i18n_exec_target:Not A Target ${TARGET}. ..")
   endif()

   IF(WIN32)
      get_property(wd_dir 
         TARGET ${TARGET} 
         PROPERTY VS_DEBUGGER_WORKING_DIRECTORY
      )
      message(NOTICE ${wd_dir})

      set_target_properties(${TARGET} PROPERTIES 
               #VS_DEBUGGER_ENVIRONMENT ${exec_path}
               VS_DEBUGGER_WORKING_DIRECTORY $<TARGET_FILE_DIR:${TARGET}>
            )
      # IF(EWX_WORKING_DIRECTORY_USE_PROJECT_WORKING_DIR)
      #    set_target_properties(${TARGET} PROPERTIES 
      #          #VS_DEBUGGER_ENVIRONMENT ${exec_path}
      #          VS_DEBUGGER_WORKING_DIRECTORY $<TARGET_FILE_DIR:${TARGET}>
      #       )
      # ELSE()
      #    set_target_properties(${TARGET} PROPERTIES 
      #       #VS_DEBUGGER_ENVIRONMENT ${exec_path}
      #       VS_DEBUGGER_WORKING_DIRECTORY $<TARGET_FILE_DIR:${TARGET}>
      #    )
   endif()
endmacro()

#==============================================================
#此宏处理多语言的自动安装到运行目录,并设置可执行程序的工作目录
macro(ewxdev_exec_target_working_directory_with_i18n TARGET)
   if(NOT TARGET ${TARGET})
      message(FATAL_ERROR "ewxdev_i18n_exec_target:Not A Target ${TARGET}. ..")
   endif()
   if(NOT EXISTS ${EWX_ROOT_DIR}/../i18n/trfile.qm)
      message(FATAL_ERROR "Not Exists File ${EWX_ROOT_DIR}/../i18n/trfile.qm")
   ENDIF()

   get_property(wd_dir 
      TARGET ${TARGET} 
      PROPERTY VS_DEBUGGER_WORKING_DIRECTORY
      )
   message(NOTICE ${wd_dir})

   set_target_properties(${TARGET} PROPERTIES 
         #VS_DEBUGGER_ENVIRONMENT ${exec_path}
         VS_DEBUGGER_WORKING_DIRECTORY $<TARGET_FILE_DIR:${TARGET}>
      )
	#set(dst_grammer_dir ${EWX_SDK_ROOT}/bin/grammar)
   #
   #file(GLOB grammer_files ${grammer_path}/*.ag)
   #list(LENGTH grammer_files len_grammers_files)
   #if(${len_grammers_files} GREATER 0)
   #   list(JOIN grammer_files "\r\n  " str_files)
      add_custom_command(TARGET ${TARGET} PRE_BUILD
                  COMMENT "---->Copy ${TARGET} I18N Files\n${str_files}\n  To \n${dst_grammer_dir}"
                  COMMAND ${CMAKE_COMMAND} -E copy ${EWX_ROOT_DIR}/../i18n/trfile.qm $<TARGET_FILE_DIR:${TARGET}> VERBATIM
      )
   #endif()
endmacro()
#==============================================================
#此宏给插件或库设置可执行程序，便于调试处理
macro(ewxdev_external_plugin_debugger_exec target exec_name)
   if(NOT EXISTS ${EWX_SDK_ROOT})
      message(FATAL_ERROR "This Macro Only Use For External Plugins Output...")
   endif()

   IF(NOT TARGET ${target})
	   message(FATAL_ERROR "ewxdev_external_plugin_debugger_exec: Invalide Target...${target}")
   ENDIF()
   if(WIN32)
      set(bin_path ${EWX_SDK_ROOT}/bin)
      set(exec_path ${bin_path}/${exec_name}.exe)
      set_target_properties(${target} PROPERTIES 
         VS_DEBUGGER_COMMAND ${exec_path}
         #VS_DEBUGGER_ENVIRONMENT ${exec_path}
         VS_DEBUGGER_WORKING_DIRECTORY ${bin_path}
      )
   endif()
endmacro()

macro(ewxdev_external_plugin_debugger_exec_simulation TARGET)
   ewxdev_external_plugin_debugger_exec(${TARGET} ewx.simulation)
endmacro()

macro(ewxdev_external_plugin_debugger_exec_mission TARGET)
   ewxdev_external_plugin_debugger_exec(${TARGET} ewx.mission)
endmacro()

macro(ewxdev_external_plugin_debugger_exec_ide TARGET)
   ewxdev_external_plugin_debugger_exec(${TARGET} ewx.ide)
endmacro()

macro(ewxdev_external_plugin_debugger_exec_review TARGET)
   ewxdev_external_plugin_debugger_exec(${TARGET} ewx.review)
endmacro()

macro(ewxdev_external_plugin_debugger_exec_modeler TARGET)
   ewxdev_external_plugin_debugger_exec(${TARGET} ewx.modeler)
endmacro()

macro(ewxdev_external_plugin_debugger_exec_scenario TARGET)
   ewxdev_external_plugin_debugger_exec(${TARGET} ewx.scenario)
endmacro()

#==========================================
# This must be in the top-level CMake file in order for CMake's unit
# testing facilities to be used; e.g. add_test(...).
# See: http://cmake.org/Wiki/CMake/Testing_With_CTest
enable_testing()